package milkyway.hightech.banking;

import milkyway.hightech.conditions.GiroAccountCond;
import milkyway.hightech.exceptions.AmountLessThanZeroException;
import milkyway.hightech.exceptions.NotEnoughMoneyException;
import milkyway.hightech.money.Currency;
import milkyway.hightech.money.Money;
import milkyway.hightech.timer.TimeEmitter;

import java.math.BigDecimal;
import java.math.BigInteger;

import java.util.Calendar;
import java.util.Observable;

public class GiroAccount extends Account
{
    private GiroAccountCond conditions;

    /**
     *
     * @param accountNumber
     * @param accountHolder
     * @param currency
     * @param conditions
     * @param calendar
     */
    public GiroAccount(int accountNumber, String accountHolder,
        Currency currency, GiroAccountCond conditions, Calendar calendar)
    {
        super(accountNumber, accountHolder, currency, calendar);
        this.conditions = conditions;
    }

    /**
     *
     * @param o
     * @param obj
     */
    @Override
    public void update(Observable o, Object obj)
    {
        if (TimeEmitter.getInstance().getCalendar().getTime().getDate() == 1)
        {
            setChanged();
            notifyObservers(this);
        }
    }

    /**
     * enters the given amount on debit and assures that.
     * the account ballance will not be less than zero.
     * @param amount the amount of money which should be entered on debid
     * @param reasonOfTransfer the description of this transaction
     */
    @Override
    public void enterOnDebit(Money amount, String reasonOfTransfer)
    {
        BigInteger b = getAccountBalance().subtract(amount.getValue());
        int dispo = b.compareTo(conditions.getDispo().negate());
        int signum = amount.getValue().signum();

        if (signum <= 0)
        {
            throw new AmountLessThanZeroException();
        }
        
        else if (dispo == -1)
        {
            throw new NotEnoughMoneyException();
        }
        
        else
        {
            update(-1, amount, reasonOfTransfer);
        }
    }

    /**
     * pays the current interest on credit or debit.
     */
    @Override
    public void payInterest()
    {
        BigDecimal d =
            new BigDecimal(getAccountBalance().divide(BigInteger.valueOf(100)));

        if (d.signum() >= 1)
        {
            d = d.multiply(BigDecimal.valueOf(conditions.getDebitInterest()));
            this.enterOnDebit(new Money(d.toBigInteger().negate(),
                                        money.getCurrency()), "pay interest");
        }
    }
}